// win32.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

#define MAX_LOADSTRING 100/* MAX_LOADSTRING 宏定义 最大字符串长度 */

// Global Variables:
HINSTANCE hInst;/* HINSTANCE 实例句柄 */								// current instance
TCHAR szTitle[MAX_LOADSTRING];/* TCHAR 类型定义 char类型 标题栏文本 */								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];/* 主窗口类名 */								// The title bar text

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
/* ATOM 宏定义 WORD类型 类型定义 unsigned short类型 */
BOOL				InitInstance(HINSTANCE, int);
/* BOOL 类型定义 int类型 */
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
/* LRESULT 宏定义 LONG_PTR 类型定义 long类型
   CALLBACK 宏定义 __stdcall
   UINT 类型定义 unsigned int类型
   WPARAM 字参数 宏定义 UINT_PTR 类型定义 unsigned int类型
   LPARAM 长字参数 宏定义 LONG_PTR 类型定义 long类型 */
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
/* APIENTRY 宏定义 WINAPI 类型定义 __stdcall
   LPSTR 类型定义 char*类型 
   WinMain(hInstance 当前实例句柄,hPrevInstance 前一个实例句柄,lpCmdLine 命令行,nCmdShow 控制窗口的显示方式) Windows函数 win32应用程序入口 */
{
 	// TODO: Place code here.
	MSG msg;
	/* MSG 类型定义 tagMSG结构*/
	HACCEL hAccelTable;
	/* HACCEL 类型定义 加速键句柄 */

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	/* LoadString(hInstance 当前实例句柄,uID 要加载的字符串,lpBuffer 接收的字符串,nBufferMax 缓冲区的大小) Windows函数 从与指定模块相关联的可执行文件中加载字符串资源，将字符串复制到缓冲区，并附加终止空字符 
	   IDS_APP_TITLE 宏定义 103 */
	LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING);
	/* IDC_WIN32 宏定义 109 */
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32);
	/* LoadAccelerators(hInstance 当前实例句柄，lpTableName 要加载的加速器表的名称) Windows函数 加载指定的加速器表
	   LPCTSTR 类型定义 const TCHAR*类型 */

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	/* GetMessage(lpMSG 消息结构的指针,hWnd 窗口句柄,wMsgFilterMin 要检索的最低消息值的整数值,wMsgFilterMax 要检索的最高消息值的整数值) Windows函数 从调用线程的消息队列中检索消息
	   LPMSG 类型定义 tagMSG的结构指针 */
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
		/* TranslateAccelerator(hWnd 窗口句柄,hAccelTable 快捷键定义表,lpMsg 当前消息) Windows函数 处理加速键 */	
		{
			TranslateMessage(&msg);
			/* TranslateMessage(lpMsg 要转换的消息) Windows函数 将虚拟键消息转换为字符消息 */
			DispatchMessage(&msg);
			/* DispatchMessage(lpMsg 消息) Windows函数 将消息发送到窗口过程 */
		}
	}

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
	/* WNDCLASSEX 类型定义 WNDCLASSEXW结构类型 */

	wcex.cbSize = sizeof(WNDCLASSEX); 
	/* 该结构的大小 */

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	/* 窗口类的样式 
	   CS_HREDRAW 宏定义 0x0002 如果窗口的位置或宽度改变,将重绘窗口
	   CS_VREDRAW 宏定义 0x0001 如果窗口的位置或高度改变,将重绘窗口 */
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	/* 指向窗口过程的指针 */
	wcex.cbClsExtra		= 0;
	/* 在窗口类结构之后分配的额外字节数 */
	wcex.cbWndExtra		= 0;
	/* 在窗口实例之后分配的额外字节数 */
	wcex.hInstance		= hInstance;
	/* 包含该类的窗口过程的实例句柄 */
	wcex.hIcon			= LoadIcon(hInstance, (LPCTSTR)IDI_WIN32);
	/* 图标句柄
	   LoadIcon(hInstance 实例句柄,lpIconName 要加载的图标资源的名字) Windows函数 从与应用实例相关的可执行文件(.exe)中加载指定的图标资源 */
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	/* 光标句柄
	   LoadCursor(hInstance 实例句柄,lpCursorName要加载的光标资源的名字) Windows函数 从与应用实例相关的可执行文件(.exe)中加载指定的光标资源
	   IDC_ARROW 宏定义 MAKEINTRESOURCE(32512) */
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	/* 背景画笔的句柄
	   HBRUSH 类型定义 void*类型 画刷句柄
	   COLOR_WINDOW 宏定义 5 */
	wcex.lpszMenuName	= (LPCSTR)IDC_WIN32;
	/* 向一个空值终止的字符串,指定类菜单的资源名称,名称显示在资源文件中 */
	wcex.lpszClassName	= szWindowClass;
	/* 指向空终止字符串的指针或是原子 */
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
	/* 与窗口类相关联的小图标的句柄 */

	return RegisterClassEx(&wcex);
	/* RegisterClassEx(Ipwcx 指向一个WNDCLASSEX结构的指针) Windows函数 注册窗口 */
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   /* CreateWindow(lpClassName 窗口类名称,lpWindowName 窗口名称,
                   dwStyle 窗口样式,x 窗口初始水平位置,y 窗口初始垂直位置,
                   nWidth 窗口初始宽度,nHeight 窗口初始高度,
                   hWndParent 父窗口或所有者窗口句柄,hMemu 菜单句柄,
                   hInstance 实例句柄,lpParam 消息参数指针) Windows函数 创建窗口
	  WS_OVERLAPPEDWINDOW 宏定义 (WS_OVERLAPPED  宏定义 0x00000000L|\
	  WS_CAPTION	   宏定义 0x00C00000L|\
	  WS_SYSMENU	   宏定义 0x00080000L|\
	  WS_THICKFRAME  宏定义 0x00040000L|\
	  WS_MINIMIZEBOX 宏定义 0x00020000L|\
	  WS_MAXIMIZEBOX 宏定义 0x00010000L) 窗口样式类型
	  CW_USEDEFAULT 宏定义 ((int)0x80000000) */

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   /* ShowWindow(hWnd 窗口句柄,nCmdShow 控制窗口显示的方式) Windows函数 设置指定窗口显示状态 */
   UpdateWindow(hWnd);
   /* UpdateWindow(hWnd 要更新的窗口) Windows函数 更新窗口 */

   return TRUE;
}

//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	/* PAINTSTRUCT 类型定义 tagPAINTSTRUCT结构 */
	HDC hdc;
	/*HDC 类型定义 void*类型 设备描述句柄*/
	TCHAR szHello[MAX_LOADSTRING];
	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch (message) 
	{
		case WM_COMMAND:
		/* WM_COMMAND 宏定义 0x0111 */
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam);
			/* LOWORD() 宏定义 ((WORD)(((DWORD_PTR)(l)) & 0xffff)) 取低字节
			   HIWORD() 宏定义 ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff)) 取高字节 */
			// Parse the menu selections:
			switch (wmId)
			{
				case IDM_ABOUT:
				   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
				   /* DialogBox(hInstance 实例句柄,lpTemplate 对话框模板,hWndParent 拥有该对话框的窗口的句柄,lpDialogFunc 指向对话框的指针过程) Windwos函数 创建一个模式对话框
				      DLGPROC 类型定义 INT_PTR(CALLBACK* DLGPROC)(HWND, UINT, WPARAM, LPARAM) */
				   break;
				case IDM_EXIT:
				   DestroyWindow(hWnd);
				   /* DestroyWindow(hWnd 要销毁的窗口句柄) Windows函数 销毁指定的窗口*/
				   break;
				default:
				   return DefWindowProc(hWnd, message, wParam, lParam);
				   /* DefWindowProc(hWnd 接收消息的窗口过程的句柄,message 消息,wParam 附加消息信息字参数,lParam 附加消息信息长字参数) Windows函数 调用默认窗口过程,处理任何未被应用程序处理的窗口消息 */
			}
			break;
		case WM_PAINT:
		/*WM_PAINT 宏定义 0x000F*/
			hdc = BeginPaint(hWnd, &ps);
			/* BeginPaint(hwnd 处理被重画的窗口句柄，lpPaint 指向将接受绘画信息的PAINTSTRUCT结构指针) Windows函数 准备绘图窗口 */
			// TODO: Add any drawing code here...
			RECT rt;
			/* RECT 类型定义 tagRECT结构 描述矩形的宽度、高度、位置 */
			GetClientRect(hWnd, &rt);
			/* GetClientRect(hWnd 窗口句柄,lpRect 客户区坐标) Windows函数 获得客户区坐标 */
			DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
			/* DrawText(hDC 设备上下文句柄,lpchText 要绘制的文本的字符串的指针,nCount 字符串长度,lpRect 指向包含要格式化文本的矩形的RECT结构的指针,uFormat 格式化文本的方法) Windows函数 绘制格式化指定的矩形文本 */
			EndPaint(hWnd, &ps);
			/* EndPaint(hWnd 处理已被重绘的窗口,lpPaint 绘画信息) Windows函数 标记画在指定的窗口结束 */
			break;
		case WM_DESTROY:
		/* WM_DESTROY 宏定义 0x0002 */
			PostQuitMessage(0);
			/* PostQuitMessage(nExitCode 退出代码) Windows函数 向系统指示线程已经请求终止(退出) */
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
		/* WM_INITDIALOG 宏定义 0x0110 */
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			/* IDOK 宏定义 1
			   IDCANCEL 宏定义 2 */
			{
				EndDialog(hDlg, LOWORD(wParam));
				/*EndDialog(hDlog 对话框窗口句柄,NResult 指定从创建对话框函数返回到应用程序的值) Windows函数 清除一个模态对话框,并使系统中止对对话框的任何处理*/
				return TRUE;
			}
			break;
	}
    return FALSE;
}